﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using _2DgameServer.Controller;
using MySql.Data.MySqlClient;
using NetgameProtocol;

namespace _2DgameServer.Servers
{
    class Server
    {
        private Socket socket;
        private List<Client> clientList = new List<Client>();
        private List<Room> roomlist = new List<Room>();

        private ControllerManager controllerManager;

        public Server(int port)
        {
            //初始化控制器
            controllerManager = new ControllerManager(this);
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定
            socket.Bind(new IPEndPoint(IPAddress.Any, port));
            //监听
            socket.Listen(0);
            //开始接收
            StartAccpet();
        }
        void StartAccpet()
        {
            socket.BeginAccept(AcceptCallback, null);
        }
        void AcceptCallback(IAsyncResult iar)
        {
            Socket client = socket.EndAccept(iar);
            clientList.Add(new Client(client, this));
            StartAccpet();
        }

        public void HandleRequest(MainPack pack, Client client)
        {
            controllerManager.HandleRequest(pack, client);
        }

        public void RemoveClient(Client client)
        {
            clientList.Remove(client);
        }
        public MainPack CreateRoom(Client client,MainPack pack)
        {
            try
            {
                Room room = new Room(client, pack.Roompack[0],this);
                roomlist.Add(room);
                foreach(PlayerPack p in room.GetPlayerInFo())
                {
                    pack.Playerpack.Add(p);
                }
                pack.ReturnCode = ReturnCode.Succeed;
                return pack;
            }catch
            {
                pack.ReturnCode = ReturnCode.Field;                
                return pack;
            }
        }
        public MainPack FindRoom()
        {
            MainPack pack = new MainPack();
            pack.ActionCode = ActionCode.FindRoom;
            try
            {
                if (roomlist.Count == 0)
                {
                    pack.ReturnCode = ReturnCode.NotRoom;
                    return pack;
                }
                foreach (Room room in roomlist)
                {                  
                    pack.Roompack.Add(room.GetRoomInfo);
                }
                pack.ReturnCode = ReturnCode.Succeed;
            }
            catch(Exception e)
            {
                Console.WriteLine(e);
                pack.ReturnCode = ReturnCode.Field;
            }
            return pack;
        }
        public MainPack JoinRoom(Client client,MainPack pack)
        {
            foreach(Room r in roomlist)
            {
                if (r.GetRoomInfo.Roomname.Equals(pack.Str))
                {
                    //有房间
                    if(r.GetRoomInfo.State == 0)
                    {
                        //可以加入房间
                        r.Join(client);
                        pack.Roompack.Add(r.GetRoomInfo);
                        foreach (PlayerPack p in r.GetPlayerInFo())
                        {
                            pack.Playerpack.Add(p);
                        }
                        pack.ReturnCode = ReturnCode.Succeed;
                        return pack;
                    }
                    else
                    {
                        //房间不可加入
                        pack.ReturnCode = ReturnCode.Field;
                        return pack;
                    }
                }
            }
            //没有此房间
            pack.ReturnCode = ReturnCode.NotRoom;
            return pack;
        }
        public MainPack ExitRoom(Client client,MainPack pack)
        {
            if (client.GetRoom == null)
            {
                pack.ReturnCode = ReturnCode.Field;
                return pack;
            }

            client.GetRoom.Exit(this,client);
            pack.ReturnCode = ReturnCode.Succeed;
            return pack;
        }
        public void RemoveRoom(Room room)
        {
            roomlist.Remove(room);
        }
        public void Chat(Client client,MainPack pack)
        {
            pack.Str = client.GetUserInFo.UserName + ":"+pack.Str;
            client.GetRoom.Broadcast(client, pack);
        }
    }

}
